﻿using S7.Net;
using S7.Net.Types;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ZR.DataCollection2
{
    public static class DataConversion
    {
        /// <summary>
        /// 从byte数组获取Int16的数据
        /// </summary>
        /// <param name="buffers">byte数组</param>
        /// <param name="arrIndex">索引</param>
        /// <returns></returns>
        public static short GetInt16DataByBytes(byte[] buffers, int arrIndex)
        {
            byte[] buffer = buffers.Skip(arrIndex).Take(2).ToArray().Reverse().ToArray();
            return BitConverter.ToInt16(buffer, 0);
        }

        public static ushort GetWordDataByBytes(byte[] buffers, int arrIndex)
        {
            byte[] buffer = buffers.Skip(arrIndex).Take(2).ToArray().Reverse().ToArray();
            return BitConverter.ToUInt16(buffer, 0);
        }

        /// <summary>
        /// 从byte数组获取Int32的数据
        /// </summary>
        /// <param name="buffers">byte数组</param>
        /// <param name="arrIndex">索引</param>
        /// <returns></returns>
        public static int GetInt32DataByBytes(byte[] buffers, int arrIndex)
        {
            byte[] buffer = buffers.Skip(arrIndex).Take(4).ToArray().Reverse().ToArray();
            return BitConverter.ToInt32(buffer, 0);
        }

        /// <summary>
        /// 从byte数组获取double的数据
        /// </summary>
        /// <param name="buffers">byte数组</param>
        /// <param name="arrIndex">索引</param>
        /// <returns></returns>
        public static double GetDoubleDataByBytes(byte[] buffers, int arrIndex)
        {
            byte[] buffer = buffers.Skip(arrIndex).Take(8).ToArray().Reverse().ToArray();
            return BitConverter.ToDouble(buffer, 0);
        }

        /// <summary>
        /// 从byte数组获取float的数据
        /// </summary>
        /// <param name="buffers">byte数组</param>
        /// <param name="arrIndex">索引</param>
        /// <returns></returns>
        public static float GetFloatDataByBytes(byte[] buffers, int arrIndex)
        {
            byte[] buffer = buffers.Skip(arrIndex).Take(4).ToArray().Reverse().ToArray();
            return BitConverter.ToSingle(buffer, 0);
        }

        /// <summary>
        /// 从byte数组获取string的数据
        /// </summary>
        /// <param name="buffers">byte数组</param>
        /// <param name="startIndex">起始位置</param>
        /// <param name="startIndex">字符长度</param>
        /// <returns></returns>
        public static string GetStringDataByBytes(byte[] buffers, int startIndex, int length)
        {
            byte[] strLength = buffers.Skip(startIndex).Take(2).ToArray();
            byte byteLength = strLength[1];
            int validLength = Convert.ToInt16(byteLength);
            byte[] buffer = buffers.Skip(startIndex + 2).Take(validLength).ToArray();
            return Encoding.Default.GetString(buffer);
        }

        public static byte SetbitValue(byte data, int index, bool value)
        {
            if (index > 7 || index < 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            int v = 1 << index;
            return value ? (byte)(data | v) : (byte)(data & ~v);
        }

        public static bool GetBit(byte data, int index)
        {
            if (index > 7 || index < 0)
            {
            }
            //  0001   0010      0000 0010
            bool bit = (data & (1 << index)) != 0;
            return bit;
        }

        // DTL类型在PLC中是12字节
        internal static object GetDTL(byte[] buffers, int startIndex)
        {
            try
            {
                byte[] bytes = buffers.Skip(startIndex).Take(12).ToArray();
                if (IsAllBytesZero(bytes))
                    return Convert.ToDateTime("1970-01-01");
                return DateTimeLong.FromByteArray(bytes);
            }
            catch (Exception ex)
            {
                return Convert.ToDateTime("1970-01-01");
            }

        }

        internal static object GetChar(byte[] buffers, int startIndex)
        {
            byte[] bytes = buffers.Skip(startIndex).Take(1).ToArray();
            return Encoding.ASCII.GetString(bytes)[0];
        }

        internal static object GetDT(byte[] buffers, int startIndex)
        {
            try
            {
                byte[] bytes = buffers.Skip(startIndex).Take(8).ToArray();
                if (IsAllBytesZero(bytes))
                    return Convert.ToDateTime("1970-01-01");
                return S7.Net.Types.DateTime.FromByteArray(bytes);
            }
            catch (Exception ex)
            {
                return Convert.ToDateTime("1970-01-01");
            }
        }

        public static bool IsAllBytesZero(byte[] byteArray)
        {
            foreach (byte b in byteArray)
            {
                if (b != 0)
                {
                    return false;
                }
            }
            return true;
        }


    }
}